import { app, shell, BrowserWindow, ipcMain, screen, protocol } from 'electron'
import path from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
import { autoUpdater } from 'electron-updater'

ipcMain.on('show-dialog', (event, arg) => {
  console.log(event, arg)
  let newWindow
  newWindow = new BrowserWindow({
    height: 600,
    width: 1000,
    // alwaysOnTop: true,
    nodeIntegration: true,
    contextIsolation: false,
    autoHideMenuBar: true,
    webPreferences: {
      sandbox: false,
      webSecurity: false,
      nodeIntegration: true // 允许使用Node.js模块
    }
  })
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    newWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/about.html`)
  } else {
    newWindow.loadFile(path.join(__dirname, '../renderer/index.html'))
  }
  newWindow.on('closed', () => {
    newWindow = null
  })
})

let mainWindow // 窗体
let x,
  y,
  width = 600,
  height = 600 // 窗口位置及大小
let mx, my
let thisX1, thisX2, thisY1, thisY2 // 隐藏时的位置
let type = '',
  isDragging = false //

function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 600,
    height: 600,
    // alwaysOnTop: true,
    nodeIntegration: true,
    contextIsolation: false,
    autoHideMenuBar: true,
    frame: false,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      sandbox: false,
      webSecurity: false,
      nodeIntegration: true, // 允许使用Node.js模块
      preload: path.join(__dirname, '../preload/index.js')
    }
  })

  mainWindow.on('will-move', (e, newBounds) => {
    isDragging = true
    // 窗口数据
    x = newBounds.x
    y = newBounds.y
    width = newBounds.width
    height = newBounds.height

    // 屏幕数据
    const { workArea } = screen.getDisplayNearestPoint({ x, y })

    // 检查窗口是否贴边
    if (x + width >= workArea.x + workArea.width - 2 || y <= 0 + 2) {
      // 贴边时隐藏窗口
      if (x + width >= workArea.x + workArea.width - 2) {
        type = 'right'
        thisY1 = y
        thisY2 = y + height
      }
      if (y <= 0 + 2) {
        type = 'top'
        thisX1 = x
        thisX2 = x + width
      }
    } else {
      reset()
    }
  })

  mainWindow.on('moved', () => {
    isDragging = false
  })

  mainWindow.on('close', function () {
    mainWindow = null
  })

  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/index.html`)
  } else {
    mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'))
  }
}

function mousemove() {
  if (type === '' || mainWindow.isMaximized() || isDragging === true) return
  // 鼠标位置
  const point = screen.getCursorScreenPoint()
  mx = point.x
  my = point.y
  // 窗口尺寸
  const size = screen.getPrimaryDisplay().workAreaSize
  const screenWidth = size.width
  if (type === 'top' && my <= 0 + 2 && mx >= thisX1 - 2 && mx <= thisX2 + 2) {
    if (!mainWindow.isVisible()) {
      mainWindow.setPosition(thisX1, 0)
      mainWindow.show()
      return
    }
  }
  if (type === 'right' && mx >= screenWidth - 2 && my >= thisY1 - 2 && my <= thisY2 + 2) {
    if (!mainWindow.isVisible()) {
      mainWindow.setPosition(screenWidth - width, thisY1)
      mainWindow.show()
      return
    }
  }
  if (mainWindow.isVisible() && type !== '') {
    const wx = mainWindow.getBounds().x
    const wy = mainWindow.getBounds().y
    const width = mainWindow.getBounds().width
    const height = mainWindow.getBounds().height
    if (mx >= wx - 2 && mx <= wx + width + 2 && my >= wy - 2 && my <= wy + height + 2) {
      mainWindow.show()
    } else {
      mainWindow.hide()
    }
  }
}

function reset() {
  type = ''
  mainWindow.show()
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  createWindow()
  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })

  // 监听鼠标移动事件
  setInterval(() => {
    mousemove()
  }, 300)

  // 在你的应用准备好后，检查更新
  mainWindow.webContents.on('did-finish-load', () => {
    autoUpdater.checkForUpdates()
  })

  // 注册自定义协议
  protocol.registerBufferProtocol(
    'vite-electron',
    (request, callback) => {
      // 返回自定义的 MIME 类型和数据
      const mimeType = 'application/x-recorder'
      const data = Buffer.from('Hello, world!', 'utf8')
      callback({ mimeType, data })
    },
    (error) => {
      if (error) {
        console.error('注册协议失败')
      }
    }
  )
})

// 退出应用时清除定时器
app.on('will-quit', () => {
  clearInterval()
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.

const initWs = () => {
  const http = require('http-server') //这个会返回目录下的所有，不支持on，且连接后关闭不了连接
  var httpServer = null
  var sockets = {}
  // ws-服务器
  const WebSocketServer = require('ws').Server
  const wss = new WebSocketServer({ port: 9527 })
  wss.on('connection', (ws) => {
    console.log('client connected')
    // 并且创建'message'监听
    ws.on('message', (message) => {
      let msg = JSON.stringify(message)
      console.log(msg, 'msg')
      var recmsg = msg.split('|')
      if (recmsg[0] === 'httpopen' && recmsg.length == 2) {
        if (httpServer === null) {
          //创建Http服务
          httpServer = http.createServer()
          httpServer.listen(parseInt(recmsg[1]))
          ws.send('http 已打开，访问：http://localhost:' + recmsg[1])
        } else {
          ws.send('http 已是打开状态！')
        }
      } else if (recmsg[0] === 'httpclose' && recmsg.length == 2) {
        if (httpServer != null) {
          //关闭Http服务
          //httpServer.close();
          httpServer.close(function () {
            console.log('http closed!')
          })
          // 销毁所有打开套接：sockets
          for (var socketId in sockets) {
            console.log('socket', socketId, 'destroyed')
            sockets[socketId].destroy()
          }
          httpServer = null
          ws.send('关闭http ')
        } else {
          ws.send('http 已是关闭状态！')
        }
      } else {
        // 有客户端连接时, 打印一条日志
        ws.send('收到：' + message)
      }
      // 直接将消息打印出来
      console.log('收到：' + message)
    })
  })
}

const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
  app.quit()
} else {
  initWs()
  // app.on('second-instance', (event, argv) => {
  //   console.log(event, argv, 123)
  // })
}

if (app.isPackaged) {
  // 是否处于打包
  app.setAsDefaultProtocolClient('vite-electron')
} else {
  app.setAsDefaultProtocolClient('vite-electron', process.execPath, [path.resolve(process.argv[1])])
}

// 设置软件包更新地址
autoUpdater.setFeedURL({
  provider: 'generic',
  url: 'http://192.xxx.xxx.xx'
})
// 监听更新事件，并在检查到有新版本时进行更新
autoUpdater.on('update-available', () => {
  // 在这里根据你的需求执行更新操作，例如弹出提示框询问用户是否更新等
})

// 监听下载进度事件，可以更新进度条等UI反馈
autoUpdater.on('download-progress', (progressObj) => {
  // 在这里更新进度条等UI反馈
  console.log(progressObj)
})

// 监听更新完成事件，在更新完成后重新启动应用
autoUpdater.on('update-downloaded', () => {
  autoUpdater.quitAndInstall()
})
